package com.example.springboot.utils;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.example.springboot.common.Direction;
import com.example.springboot.common.Link;
import com.example.springboot.common.Model;
import com.example.springboot.common.Node;
import com.fasterxml.jackson.core.JsonProcessingException;

import java.util.ArrayList;
import java.util.List;

public class DirectionUtil {

    public List<Direction> createList(Model model){
        List<Direction> directionList = new ArrayList<>();
        //遍历结点
        for (Node node : model.getNodes()) {
            //对每个结点创建Direction对象、suggestion列表和StringBuffer对象
            Direction direction = new Direction();
            StringBuffer stringBuffer = new StringBuffer();
            StringBuffer stringClash= new StringBuffer();
            List<String> suggestion = new ArrayList<>();
            //对每个结点创建两个list，存储指向结点的id
            List<String> goodNodes = new ArrayList<>();
            List<String> badNodes = new ArrayList<>();
            //若结点为根节点、跳过
            if (node.getId().equals("root")) {
            }
            else {
                if (node.getColor().equals("#89B8CA")) { //如果结点性质为有用，存储id，添加方向
                    direction.setId(node.getId());
                    stringBuffer.append("保证 \"").append(direction.getId()).append("\" 功能的实现");
                    suggestion.add(stringBuffer.toString());
                    stringBuffer.delete(0,stringBuffer.length());
                    //
                    childNodes(model,node,goodNodes,badNodes);
                    //技术冲突
                    if (!goodNodes.isEmpty() && !badNodes.isEmpty()) {
                        stringClash.append("技术冲突: 系统应具有 \"").append(node.getId()).append("\" ");
                        techClash(direction,node,stringBuffer,stringClash,suggestion,goodNodes,badNodes);
                    }
                    else if (goodNodes.isEmpty() && badNodes.isEmpty()) {
                        direction.setType("#e0e5df");
                    }
                    //物理冲突
                    else if (goodNodes.isEmpty()){
                        direction.setClash("物理冲突");
                        direction.setType("#f8ebd8");
                        stringBuffer.append("避免 ");
                        stringClash.append("物理冲突: 系统中应具有 \"").append(direction.getId()).append("\" ,但同时会伴生 ");
                        for (String bad : badNodes){
                            stringBuffer.append("\"").append(bad).append("\" ");
                            stringClash.append("\"").append(bad).append("\" ");
                        }
                        stringBuffer.append("的产生");
                        suggestion.add(stringBuffer.toString());
                        stringBuffer.delete(0,stringBuffer.length());
                    }
                    //普通有用类
                    else {
                        direction.setType("#e0e5df");
                        stringBuffer.append("不会消除 ");
                        for (String good : goodNodes)
                            stringBuffer.append("\"").append(good).append("\" ");
                        stringBuffer.append("的功能");
                        suggestion.add(stringBuffer.toString());
                        stringBuffer.delete(0,stringBuffer.length());
                    }
                    if (node.getPreId() != null){
                        stringBuffer.append("尽可能不依靠 \"").append(node.getPreId()).append("\" ");
                        suggestion.add(stringBuffer.toString());
                    }
                }
                else if (node.getColor().equals("#ca8989")) {
                    direction.setId(node.getId());
                    stringBuffer.append("尽可能避免 \"").append(direction.getId()).append("\" 的负面影响");
                    suggestion.add(stringBuffer.toString());
                    stringBuffer.delete(0,stringBuffer.length());
                    //
                    childNodes(model,node,goodNodes,badNodes);
                    //技术冲突
                    if (!goodNodes.isEmpty() && !badNodes.isEmpty()) {
                        stringClash.append("技术冲突: 系统中本身不应该存在 \"").append(node.getId()).append("\" ");
                        techClash(direction,node,stringBuffer,stringClash,suggestion,goodNodes,badNodes);
                    }
                    //无子节点
                    else if (goodNodes.isEmpty() && badNodes.isEmpty()) {
                        direction.setType("#ead0d1");
                    }
                    //物理冲突
                    else if (!goodNodes.isEmpty()){
                        direction.setClash("物理冲突");
                        direction.setType("#f8ebd8");
                        stringBuffer.append("不会消除 ");
                        stringClash.append("物理冲突: 系统中本身不应该存在 \"").append(direction.getId()).append("\" ,但又需要用于提供 ");
                        for (String good : goodNodes) {
                            stringBuffer.append("\"").append(good).append("\" ");
                            stringClash.append("\"").append(good).append("\" ");
                        }
                        stringBuffer.append("的功能");
                        suggestion.add(stringBuffer.toString());
                        stringBuffer.delete(0,stringBuffer.length());
                    }
                    //普通有害类
                    else {
                        direction.setType("#ead0d1");
                        stringBuffer.append("避免 ");
                        for (String bad : badNodes)
                            stringBuffer.append("\"").append(bad).append("\" ");
                        stringBuffer.append("的产生");
                        suggestion.add(stringBuffer.toString());
                        stringBuffer.delete(0,stringBuffer.length());
                    }
                    if (node.getPreId() != null){
                        stringBuffer.append("尽可能保留 \"").append(node.getPreId()).append("\" ");
                        suggestion.add(stringBuffer.toString());
                    }
                }
                direction.setSuggestion(suggestion);
                direction.setClashMessage(stringClash.toString());
                directionList.add(direction);
            }
        }
        return directionList;
    }

    //将传入的JSON字符串转为Model对象
    public Model transform (String jsonString) throws JsonProcessingException {
        JSONObject json = JSONUtil.parseObj(jsonString);
        Model model = JSONUtil.toBean(json,Model.class);
        JSONArray jsonArray1 = new JSONArray(json.getObj("nodes"));
        JSONArray jsonArray2 = new JSONArray(json.getObj("links"));
        model.setNodes(jsonArray1.toList(Node.class));
        List<Link> linkList = jsonArray2.toList(Link.class);

        //数据清洗
        linkList.removeIf(link -> link.getText().equals("需要") || link.isHide());
        model.setLinks(linkList);
        return model;
    }

    //对关系进行遍历，找到传入结点的子节点并添加到列表中，找到当前结点的父节点
    public void childNodes(Model model, Node node, List<String> gNodes, List<String> bNodes){
        for (Link link : model.getLinks()) { //对关系进行遍历
            if (link.getTo().equals(node.getId())) { //找到当前结点的父结点
                node.setPreId(link.getFrom());
            }
            if (link.getFrom().equals(node.getId())) {  //找到父结点为当前结点的关系
                for (Node node1 : model.getNodes()){    //对结点进行遍历
                    if (node1.getId().equals(link.getTo())) {   //找到子节点
                        if (node1.getColor().equals("#89B8CA")){    //对子结点的性质进行判断，并将其添加到对应列表中
                            gNodes.add(node1.getId());
                        }
                        else {
                            bNodes.add(node1.getId());
                        }
                    }
                }
            }
        }
    }

    //对技术冲突的处理
    public void techClash(Direction direction,Node node,StringBuffer sb,StringBuffer sc,List<String> strings,List<String> goodNodes,List<String> badNodes){
        StringBuffer temp1 = new StringBuffer();
        StringBuffer temp2 = new StringBuffer();
        direction.setClash("技术冲突");
        direction.setType("#f8ebd8");
        sb.append("不会消除 ");
        if (node.getColor().equals("#89B8CA"))
            temp1.append(",用于提供 ");
        else
            temp2.append(",但需要用于提供 ");
        for (String good : goodNodes) {
            sb.append("\"").append(good).append("\" ");
            temp1.append("\"").append(good).append("\" ");
            temp2.append("\"").append(good).append("\" ");
        }
        if (node.getColor().equals("#89B8CA"))
            sc.append(temp1.toString());
        sb.append("的功能");
        strings.add(sb.toString());
        sb.delete(0,sb.length());
        sb.append("避免 ");
        if (node.getColor().equals("#89B8CA"))
            sc.append(",但同时会伴生 ");
        else
            sc.append(",且会伴生 ");
        for (String bad : badNodes){
            sb.append("\"").append(bad).append("\" ");
            sc.append("\"").append(bad).append("\" ");
        }
        sb.append("的产生");
        strings.add(sb.toString());
        sb.delete(0,sb.length());
        if (node.getColor().equals("#ca8989"))
            sc.append(temp2.toString());
    }

    public List<String> linksToString(String jsonString) throws JsonProcessingException {
        Model model = transform(jsonString);
        StringBuffer stringBuffer = new StringBuffer();
        List<String> result = new ArrayList<>();
        List<Link> linkList = model.getLinks();
        for (Link link : linkList) {
            for (Node node : model.getNodes()){
                if (node.getId().equals(link.getFrom())){
                    if (node.getColor().equals("#89B8CA")){
                        stringBuffer.append("有用特性 \"").append(node.getId()).append("\" ");
                    }
                    else if (node.getColor().equals("#ca8989")){
                        stringBuffer.append("有害特性 \"").append(node.getId()).append("\" ");
                    }
                }
            }
            for (Node node : model.getNodes()){
                if (node.getId().equals(link.getTo())){
                    if (node.getColor().equals("#89B8CA")){
                        stringBuffer.append("产生了有用特性 \"").append(node.getId()).append("\"");
                    }
                    else if (node.getColor().equals("#ca8989")){
                        stringBuffer.append("产生了有害特性 \"").append(node.getId()).append("\"");
                    }
                }
            }
            result.add(stringBuffer.toString());
            stringBuffer.delete(0,stringBuffer.length());
        }
        return result;
    }


}
